指定したウェアハウスでリソースが足りない時に一時的にリソースを増強してくれる「Query Acceleration」を試してみた #SnowflakeDB
※本エントリは、Snowflakeをもっと使いこなそう! Advent Calendar 2022の16日目の記事となります。
さがらです。
Snowflakeで、指定したウェアハウスでリソースが足りない時に一時的にリソースを増強してくれる「Query Acceleration」を試してみたので、その内容をまとめてみます。
※記事執筆時点(2022年12月7日)では、本機能はプレビュー機能ですのでご注意ください。
Query Accelerationとは
Query AccelerationはSnowflakeのウェアハウスに対して行う設定で、有効化していると、通常のクエリよりも多くのリソースを使用する外れ値に該当するクエリが発行された時に一時的にリソースを増強し、対象の外れ値クエリに対するパフォーマンスを向上できる機能となっております。
特に、BIツールのように非定型に自由に発行されるクエリを処理するウェアハウスにおいてメリットを受ける可能性が高い機能です。
より詳細な仕様については、公式Docも併せてご確認ください。
試してみた
それでは、実際にQuery Accelerationがどんな機能か試してみます!
前提
今回、以下のSnowflakeサンプルデータであるSNOWFLAKE_SAMPLPE_DATA
データベースのTPCDS_SF10TCL
というスキーマにあるテーブルに対して、サイズXSのシングルクラスタのウェアハウスで以下のクエリを実行してみてみました。(このクエリは、こちらの海外での検証記事からの引用です。)
かかった時間は「4分49秒」でした。正直、時間がかかりすぎていますよね。このクエリに対して、Query Accelerationが適用できるか検証してみます。
select d.d_year as "Year", i.i_brand_id as "Brand ID", i.i_brand as "Brand", sum(ss_net_profit) as "Profit" from snowflake_sample_data.tpcds_sf10tcl.date_dim d ,snowflake_sample_data.tpcds_sf10tcl.store_sales s ,snowflake_sample_data.tpcds_sf10tcl.item i where d.d_date_sk = s.ss_sold_date_sk and s.ss_item_sk = i.i_item_sk and i.i_manufact_id = 939 and d.d_moy = 12 group by d.d_year, i.i_brand, i.i_brand_id order by 1, 4, 2 limit 200;
Query Accelerationが適用可能かどうかの判断
まず前述のクエリを実行した際のクエリIDを用いて、SYSTEM$ESTIMATE_QUERY_ACCELERATION
関数を実行して、このクエリに対してQuery Accelerationが適用可能かどうかを確かめてみます。
PARSE_JSON
関数と併せることで、VARIANT型の値として返す事ができます。
select parse_json(system$estimate_query_acceleration('01a8cc45-0000-a2c8-0000-95810001903e'));
上記のクエリを実行することで、下図の様に結果が返ってきます。注目すべきはstatus
とestimatedQueryTimes
です。
status
がeligible
の場合、対象のクエリはQuery Accelerationが適用可能であることを示しています。
estimatedQueryTimes
では、Query Accelerationの設定値であるスケールファクターをどの値にすることで、どのくらいの秒数でこのクエリの結果が返ってくることを見込めるかがわかります。
また、ACCOUNT_USAGE
スキーマのQUERY_ACCELERATION_ELIGIBLE
ビューを用いても、Query Accelerationが適用可能なクエリを確認可能です。こちらのビューはデータ更新までにラグがありますが、運用時には定期的にこのビューを監視するのが良さそうですね。
以下は、QUERY_ACCELERATION_ELIGIBLE
ビューに対するクエリサンプルです。
use role accountadmin; select query_id, eligible_query_acceleration_time from snowflake.account_usage.query_acceleration_eligible order by eligible_query_acceleration_time desc;
対象のウェアハウスでQuery Accelerationを有効化
では続いて、対象のウェアハウスでQuery Accelerationを有効化し、クエリの実行速度を確かめてみます!
まず、対象のウェアハウスでのQuery Accelerationの有効化方法ですが、SnowsightのGUIでも、SQLでも、変更可能です。
SnowsightからQuery Accelerationを有効化
対象のウェアハウスの設定画面から、クエリアクセラレーション
を有効化し、スケール係数
を任意の値に設定すればOKです。
SQLで有効化
alter warehouse
コマンドで対象のウェアハウスに対し、enable_query_acceleration = true
にし、query_acceleration_max_scale_factor
は任意の値を設定して、このコマンドを実行すればOKです。
alter warehouse <ウェアハウス名> set enable_query_acceleration = true query_acceleration_max_scale_factor = 8;
Query Accelerationの有効化した後の実行速度検証
次に、Query Accelerationの有効化した後にどのようにクエリ実行速度が改善されるかを見てみます。
さきほどSYSTEM$ESTIMATE_QUERY_ACCELERATION
関数を実行した際は、下図のような結果でしたので、スケールファクターはコスパが良さそうな「4」と最大値である「17」で試してみます。
また、キャッシュの影響がないように、このセッションでのキャッシュを無効化しておきます。
alter session set use_cached_result = false;
Query Accelerationを有効化していない場合
こちらは参考値として、Query Accelerationを有効化していない場合のクエリプロファイルも見ておきます。TableScanが99.0%ということで、明らかにテーブルスキャンに時間がかかっていましたね。
スケールファクター「4」での検証
まず、下記のクエリを実行してQuery Accelerationを有効化します。スケールファクターに該当するquery_acceleration_max_scale_factor
は「4」に設定します。
alter warehouse acceleration_test_wh set enable_query_acceleration = true query_acceleration_max_scale_factor = 4;
この上で、対象のクエリを実行すると「40秒」で結果が返ってきました。SYSTEM$ESTIMATE_QUERY_ACCELERATION
関数では「67秒」という予測でしたが、この予測値よりも非常に早く結果が返ってきましたね。
クエリプロファイルを見ると、一番時間がかかっていたTableScanの実行時間の比率が少し下がっていることがわかります。
また、注目していただきたいのは「統計」欄のPartitions scanned by service
とScans selected for acceleration
です。
Partitions scanned by service
はQuery Accelerationによってスケールしたリソースによってスキャンされたマイクロパーティションの数を意味しており、Scans selected for acceleration
はQuery Accelerationによってスキャンが高速化されたテーブル数を意味しています。
結果を見ると、Partitions scanned by service
は「44987」、Scans selected for acceleration
は「1」ということで、Query Accelerationが活きているのがわかりますね!
スケールファクター「17」での検証
まず、下記のクエリを実行してQuery Accelerationを有効化します。スケールファクターに該当するquery_acceleration_max_scale_factor
は「17」に設定します。
alter warehouse acceleration_test_wh set enable_query_acceleration = true query_acceleration_max_scale_factor = 17;
この上で、対象のクエリを実行すると「32秒」で結果が返ってきました。SYSTEM$ESTIMATE_QUERY_ACCELERATION
関数では「26秒」という予測でしたが、この予測値よりも遅く結果が返ってきました。
クエリプロファイルを見ると、スケールファクター「4」の時と比べても、各プロセスの実行時間の比率にそこまで変化があるようには見えませんでした。
「統計」欄を見ると、Partitions scanned by service
は「45887」、Scans selected for acceleration
は「1」ということで、スケールファクター「4」の時と比べると少しだけ上がっていますね!これが、スケールファクター「4」の時と比べて、実行時間が8秒ほど早くなったことにもつながっているのだと思います。
Query Accelerationのコストについて
Query Accelerationのコストですが、使用したリソース分、秒単位で支払う課金体系となっております。スケールしたリソース1つに付き1時間1クレジット、サービス利用として1時間1クレジット、それぞれかかるようです。
また、コストの確認方法ですがGUIの管理画面からも確認可能ですし、SQLからでも確認可能です。
以下では、SQLを用いた場合の確認方法について記しておきます。
ACCOUNT_USAGEのQUERY_ACCELERATION_HISTORYビュー
select warehouse_name, sum(credits_used) as total_credits_used from snowflake.account_usage.query_acceleration_history where start_time >= date_trunc(month, current_date) group by 1 order by 2 desc;
INFORMATION_SCHEMAのQUERY_ACCELERATION_HISTORY関数
select * from table(information_schema.query_acceleration_history( date_range_start=>dateadd(h, -12, current_timestamp)));
本機能の注意点
私も試してみた上での注意点としては、対象のウェアハウスで時間がかかるクエリ全てにQuery Accelerationが対応する訳ではありません。
例えば、Snowsightに最初からあるワークシート上のサンプルデータに対する下記のクエリを、サイズMEDIUMのシングルクラスタのウェアハウスで実行したところ、2分44秒かかりましたがSYSTEM$ESTIMATE_QUERY_ACCELERATION
関数を実行しても、Query Accelerationの対象とならない"status": "ineligible"
と返ってきてしまいました。
select /* { "query":"query96","streamId":0,"querySequence":1 } */ count(*) from store_sales ,household_demographics ,time_dim, store where ss_sold_time_sk = time_dim.t_time_sk and ss_hdemo_sk = household_demographics.hd_demo_sk and ss_store_sk = s_store_sk and time_dim.t_hour = 8 and time_dim.t_minute >= 30 and household_demographics.hd_dep_count = 6 and store.s_store_name = 'ese' order by count(*) limit 100;
Query Acceleration機能の前提としては、基本的には通常のウェアハウスで運用していただき、もしパフォーマンスが出ていないクエリがあった場合には、前述のSYSTEM$ESTIMATE_QUERY_ACCELERATION
関数や、ACCOUNT_USAGE
スキーマのQUERY_ACCELERATION_ELIGIBLE
ビューを用いて、Query Accelerationが有効かを確認しその上でQuery Accelerationを有効化する、というプロセスが必要だと思います。
クラスタリングの設定やクエリの書き方1つでもパフォーマンスがだいぶ変わる可能性もありますので、Query Accelerationやウェアハウスのサイズアップに頼りすぎないように、注意しましょう!
最後に
Snowflakeで、指定したウェアハウスでリソースが足りない時に一時的にリソースを増強してくれる「Query Acceleration」を試してみました。
クラスタリングの設定やクエリの内容を見直しても十分にパフォーマンスが出ない、しかしウェアハウスのサイズを上げるのは過剰、そんなときに一度検討いただきたい機能ですね!